Skip to content

Added LOGO track#328

Open
pmustonebi wants to merge 2 commits into
ebi-webcomponents:mainfrom
pmustonebi:add-logo-track
Open

Added LOGO track#328
pmustonebi wants to merge 2 commits into
ebi-webcomponents:mainfrom
pmustonebi:add-logo-track

Conversation

@pmustonebi

Copy link
Copy Markdown
Collaborator

No description provided.

@pmustonebi pmustonebi requested a review from dlrice April 15, 2026 13:37
@netlify

netlify Bot commented Apr 15, 2026

Copy link
Copy Markdown

Deploy Preview for cozy-marzipan-abb3b4 ready!

Name Link
🔨 Latest commit 6b40820
🔍 Latest deploy log https://app.netlify.com/projects/cozy-marzipan-abb3b4/deploys/69df949280e3d50008487d3a
😎 Deploy Preview https://deploy-preview-328--cozy-marzipan-abb3b4.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment on lines +130 to +132
const end = Math.round(this["display-end"] ?? this.length ?? start);

if (end < start) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the user doesn't set display-end the position mixin defaults it to a special value, -1, meaning "show everything to the end" (it's named WHOLE_SEQ in nightingale-new-core).

Because ?? only falls back on null/undefined (not -1), end becomes -1, and the if (end < start) return; on the next line bails out so nothing is drawn. withZoom already handles this, we just need to do the same when choosing end:

const rawEnd = this["display-end"];
const end = Math.round(rawEnd && rawEnd !== -1 ? rawEnd : (this.length ?? start));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be resolved, please check

Comment on lines +107 to +108
// Most-conserved nucleotide at the bottom of the stack
letters.sort((a, b) => b.heightFraction - a.heightFraction);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed on other logo plots eg https://weblogo.threeplusone.com/examples.html they have the largest letters on top while this PR has them on the bottom. I just wanted to doublecheck which way you want it?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated to set the largest letter at the top.


@customElementOnce("nightingale-logo-track")
export default class NightingaleLogoTrack extends withManager(
withZoom(withHighlight(NightingaleElement))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The component mixes in withHighlight currently doesn't draw the highlighted region or reacts to those attributes. withHighlight on its own only tracks which region is highlighted and then each component then needs to implement how the highlight is rendered.

There's a ready-made mixin for exactly this: withSVGHighlight (see how nightingale-variation uses it). It gives you createHighlightGroup() and a working updateHighlight(). It would involve calling createHighlightGroup() in createTrack() and updateHighlight() inside refresh(), and the highlight rectangle should then work.

"types": "dist/index.d.ts",
"scripts": {
"build": "rollup --config ../../rollup.config.mjs",
"test": "../../node_modules/.bin/jest --config ../../jest.config.js ./tests/*"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test script runs jest against ./tests/*, but there's no tests folder in the package yet, so yarn test here doesn't actually run anything.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be resolved, please check

Comment on lines +158 to +174
parts.push(
`<text ` +
`transform="translate(${centerX.toFixed(2)},${baselineY.toFixed(2)}) scale(${scaleX.toFixed(3)},${scaleY.toFixed(3)})" ` +
`text-anchor="middle" ` +
`font-family="Arial,Helvetica,sans-serif" font-size="${FONT_SIZE}" font-weight="bold" ` +
`fill="${color}">${item.nucleotide}</text>`
);
}
}

// Draw margin overlays to mask letters that extend into margin areas
parts.push(
`<rect x="0" y="0" width="${marginLeft}" height="${height}" fill="${marginColor}" pointer-events="none"/>`,
`<rect x="${width - marginRight}" y="0" width="${marginRight}" height="${height}" fill="${marginColor}" pointer-events="none"/>`,
`<rect x="${marginLeft}" y="0" width="${width - marginLeft - marginRight}" height="${marginTop}" fill="${marginColor}" pointer-events="none"/>`,
`<rect x="${marginLeft}" y="${height - marginBottom}" width="${width - marginLeft - marginRight}" height="${marginBottom}" fill="${marginColor}" pointer-events="none"/>`
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assembles the SVG as one big string and assigns it with innerHTML on every refresh. It works, but two things:

  1. refresh() runs on every zoom/pan frame, and this throws away and re-parses the whole column DOM each time which takes bit of time.
  2. The other tracks (have a look at nightingale-linegraph-track) build and update their SVG with d3's "data join" — selectAll(...).data(...).join("text") which only touches the elements that actually changed and keeps the code consistent across the repo.

Moving to a d3 join would make it both faster and more in keeping with the rest of the codebase.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be resolved, please check


// Draw margin overlays to mask letters that extend into margin areas
parts.push(
`<rect x="0" y="0" width="${marginLeft}" height="${height}" fill="${marginColor}" pointer-events="none"/>`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The withMargin mixin you're already using provides a renderMarginOnGroup(group) helper that draws exactly the four rectangles margin for you (and reuses them rather than recreating them). nightingale-linegraph-track shows the usage. Switching to it is less code to maintain, and you'll stay in sync automatically if the shared margin behaviour ever changes.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be resolved, please check

Comment on lines +10 to +14
const NUCLEOTIDE_COLORS: Record<string, string> = {
A: "#00CC00",
C: "#0000CC",
G: "#FFB300",
U: "#CC0000",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you consider extending to work with amino acids too?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! Updated to add this capability

@netlify

netlify Bot commented Jun 10, 2026

Copy link
Copy Markdown

Deploy Preview for cozy-marzipan-abb3b4 ready!

Name Link
🔨 Latest commit 18c4e19
🔍 Latest deploy log https://app.netlify.com/projects/cozy-marzipan-abb3b4/deploys/6a295160f9546d0008a3c38a
😎 Deploy Preview https://deploy-preview-328--cozy-marzipan-abb3b4.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants